<!DOCTYPE html>
<html>
<body>
<p>Test sharing SharedArrayBuffers between dedicated workers.</p>
<div id="result"></div>
<script type="text/javascript">
function log(message)
{
    document.getElementById("result").innerHTML += message + "</br>";
}

var testCases = [
    "testSendSharedArrayBuffer",
    "testSendInt8Array",
    "testSendUint8Array",
    "testSendUint8ClampedArray",
    "testSendInt16Array",
    "testSendUint16Array",
    "testSendInt32Array",
    "testSendUint32Array",
    "testSendFloat32Array",
    "testSendFloat64Array",
];
var testIndex = 0;

function logPendingMessages() {
    if (pendingWorkerReplies > 0) return;
    workerMessages.forEach(log);
    workerMessages = [];
    secondaryWorkerMessages.forEach(log);
    secondaryWorkerMessages = [];
}

function runNextTest()
{
    if (pendingWorkerReplies > 0) return;
    if (testIndex < testCases.length) {
        testIndex++;
        try {
            window[testCases[testIndex - 1]]();
        } catch (ex) {
            log("FAIL: unexpected exception " + ex);
            runNextTest();
        }
    } else {
        log("DONE");
        if (window.testRunner)
            testRunner.notifyDone();
    }
}

function testSendSharedArrayBuffer()
{
    runSendTest("SharedArrayBuffer");
}

function testSendInt8Array()
{
    runSendTest("Int8Array");
}

function testSendUint8Array()
{
    runSendTest("Uint8Array");
}

function testSendUint8ClampedArray()
{
    runSendTest("Uint8ClampedArray");
}

function testSendInt16Array()
{
    runSendTest("Int16Array");
}

function testSendUint16Array()
{
    runSendTest("Uint16Array");
}

function testSendInt32Array()
{
    runSendTest("Int32Array");
}

function testSendUint32Array()
{
    runSendTest("Uint32Array");
}

function testSendFloat32Array()
{
    runSendTest("Float32Array");
}

function testSendFloat64Array()
{
    runSendTest("Float64Array");
}

function initializeTypedArray(ta, length) {
    var i;
    for (i = 0; i < length; ++i)
        ta[i] = i;
}

function runSendTest(name)
{
    var length = 8;
    var type = window[name];
    var sab;
    var ta;
    var msg;

    log("Running " + name + " test case");

    if (name == 'SharedArrayBuffer') {
        sab = new SharedArrayBuffer(length);
        ta = new Uint8Array(sab);
        msg = {name: name, data: sab, length: length};
    } else {
        sab = new SharedArrayBuffer(length * type.BYTES_PER_ELEMENT);
        ta = new type(sab);
        msg = {name: name, data: ta, length: length};
    }

    initializeTypedArray(ta, length);

    // Don't allow passing a SharedArrayBuffer in the transfer list.
    try {
      worker.postMessage(msg, [sab]);
      log("FAIL: Passing SharedArrayBuffer in the transfer list did not throw.");
    } catch (e) {
      log("PASS: Passing SharedArrayBuffer in the transfer list threw.");
    }

    // Without Atomics, we can't safely test modifying the contents of the
    // SharedArrayBuffer. All we can test for now is that the SharedArrayBuffer
    // is not neutered when transferred to a Worker.
    pendingWorkerReplies += 2;
    worker.postMessage(msg);
    secondaryWorker.postMessage(msg);

    if (sab.length === 0)
        log("FAIL: SharedArrayBuffer was neutered during transfer.");
    else
        log("PASS: SharedArrayBuffer not neutered during transfer.");

    // Ensure the data wasn't changed.
    for (i = 0; i < length; ++i) {
        if (ta[i] != i) {
            log("FAIL: Original data changed during transfer. Expected " + i +
                " got " + ta[i]);
            break;
        }
    }
    if (i == length)
        log("PASS: Original data not changed during transfer.");
}

if (window.testRunner) {
    testRunner.dumpAsText();
    testRunner.waitUntilDone();
}

if (window.SharedArrayBuffer) {
    var worker = new Worker('../resources/worker-sharedarraybuffer-transfer.js');
    var secondaryWorker = new Worker('../resources/worker-sharedarraybuffer-transfer.js');
    var pendingWorkerReplies = 0;
    var workerMessages = [];
    var secondaryWorkerMessages = [];

    runNextTest();

    worker.onmessage = function(e) {
        if (e.data != 'DONE') {
            // The worker sent a pass/fail message.
            workerMessages.push(e.data);
        } else {
            pendingWorkerReplies--;
            logPendingMessages();
            runNextTest();
        }
    };
    secondaryWorker.onmessage = function(e) {
        if (e.data != 'DONE') {
            // The worker sent a pass/fail message.
            secondaryWorkerMessages.push(e.data);
        } else {
            pendingWorkerReplies--;
            logPendingMessages();
            runNextTest();
        }
    };
} else {
    log("SharedArrayBuffers are not enabled -- skipping test.");
    testRunner.notifyDone();
}

</script>
</body>
</html>
